package gui.houseeditor;

import io.BaseHouseReader;
import io.BaseHouseWriter;
import io.HouseChars;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.ButtonGroup;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileNameExtensionFilter;

@SuppressWarnings("serial")
public class HouseEditor extends JFrame {

	private HouseEditorPane worldPane;
	private JScrollPane centerPane;

	public HouseEditor(int w, int h) {
		super("TileWorld Editor");
		worldPane = new HouseEditorPane(w, h);
		initComponents();
	}

	public HouseEditor(int w, int h, int cellSize) {
		super("TileWorld Editor");
		worldPane = new HouseEditorPane(w, h, cellSize);
		initComponents();
	}

	private void initComponents() {

		this.setLayout(new BorderLayout());
		JPanel northPane = new JPanel(new FlowLayout());

		ActionListener l = new ListenerParametri();

		ButtonGroup group = new ButtonGroup();

		JRadioButton muro = new JRadioButton("Wall");
		muro.setActionCommand(ListenerParametri.WALL_COMMAND);
		muro.addActionListener(l);
		group.add(muro);
		northPane.add(muro);

		JRadioButton lamp = new JRadioButton("Lampadina");
		lamp.setActionCommand(ListenerParametri.LAMPADINA_SPENTA);
		lamp.addActionListener(l);
		group.add(lamp);
		northPane.add(lamp);

		JRadioButton porta = new JRadioButton("Porta");
		porta.setActionCommand(ListenerParametri.PORTA);
		porta.addActionListener(l);
		group.add(porta);
		northPane.add(porta);

		JRadioButton persona = new JRadioButton("Persona");
		persona.setActionCommand(ListenerParametri.PERSONA_COMMAND);
		persona.addActionListener(l);
		group.add(persona);
		northPane.add(persona);

		JRadioButton cancella = new JRadioButton("Blank");
		cancella.setSelected(true);
		cancella.setActionCommand(ListenerParametri.BLANK_COMMAND);
		cancella.addActionListener(l);
		group.add(cancella);
		northPane.add(cancella);

		add(northPane, BorderLayout.NORTH);
		add(centerPane = new JScrollPane(worldPane), BorderLayout.CENTER);

		JMenuBar barra = new JMenuBar();

		JMenu file = new JMenu("File");
		JMenuItem salva = new JMenuItem("Save...");
		JMenuItem apri = new JMenuItem("Open...");
		salva.addActionListener(new ListenerMenu());
		salva.setActionCommand(ListenerMenu.SAVE_COMMAND);
		apri.addActionListener(new ListenerMenu());
		apri.setActionCommand(ListenerMenu.OPEN_COMMAND);
		file.add(apri);
		file.add(salva);

		barra.add(file);

		this.setJMenuBar(barra);

		setLocationByPlatform(true);

		pack();
	}

	private class ListenerParametri implements ActionListener {

		public static final String BLANK_COMMAND = "blank",
				WALL_COMMAND = "wall", LAMPADINA_ACCESA = "accesa",
				PERSONA_COMMAND = "persona", LAMPADINA_SPENTA = "spenta",
				PORTA = "porta";

		public void actionPerformed(ActionEvent ae) {
			String command = ae.getActionCommand();
			if (command.equals(BLANK_COMMAND)) {
				worldPane.setPaintingObject(HouseModel.HouseObject.BLANK);
			} else if (command.equals(WALL_COMMAND)) {
				worldPane.setPaintingObject(HouseModel.HouseObject.WALL);
			} else if (command.equals(LAMPADINA_ACCESA)) {
				worldPane
						.setPaintingObject(HouseModel.HouseObject.LAMPADINA_ACCESA);
			} else if (command.equals(PERSONA_COMMAND)) {
				worldPane.setPaintingObject(HouseModel.HouseObject.PERSONA);
			} else if (command.equals(LAMPADINA_SPENTA)) {
				worldPane
						.setPaintingObject(HouseModel.HouseObject.LAMPADINA_SPENTA);
			} else if (command.equals(PORTA)) {
				worldPane.setPaintingObject(HouseModel.HouseObject.PORTA);
			}
		}
	}

	private class ListenerMenu implements ActionListener {

		public static final String SAVE_COMMAND = "save",
				OPEN_COMMAND = "open";

		public void actionPerformed(ActionEvent ae) {
			String command = ae.getActionCommand();
			if (command.equals(SAVE_COMMAND)) {
				JFileChooser jfc = new JFileChooser();
				jfc.setFileFilter(new FileNameExtensionFilter("TileWorld maps",
						"twm"));
				int res = jfc.showSaveDialog(HouseEditor.this);
				if (res != JFileChooser.APPROVE_OPTION)
					return;
				File outFile = jfc.getSelectedFile();
				try {
					writeToFile(outFile);
				} catch (IOException ioe) {
					JOptionPane.showMessageDialog(
							HouseEditor.this,
							"<html>THe following errors occourred:<br>"
									+ ioe.getMessage(), "Warning",
							JOptionPane.WARNING_MESSAGE);
				}
			} else if (command.equals(OPEN_COMMAND)) {
				JFileChooser jfc = new JFileChooser();
				jfc.setFileFilter(new FileNameExtensionFilter("TileWorld maps",
						"twm"));
				int res = jfc.showOpenDialog(HouseEditor.this);
				if (res != JFileChooser.APPROVE_OPTION)
					return;
				File inFile = jfc.getSelectedFile();
				try {
					readFromFile(inFile);
				} catch (IOException ioe) {
					JOptionPane.showMessageDialog(
							HouseEditor.this,
							"<html>THe following errors occourred:<br>"
									+ ioe.getMessage(), "Warning",
							JOptionPane.WARNING_MESSAGE);
				}
			}
		}

		private void readFromFile(File inFile) throws IOException {
			BaseHouseReader reader = new BaseHouseReader(new FileReader(inFile));
			HouseEditor.this.remove(centerPane);
			worldPane = new HouseEditorPane(reader.getWidth(),
					reader.getHeight());
			for (int i = 0; i < reader.getHeight(); i++)
				for (int j = 0; j < reader.getWidth(); j++) {
					switch (reader.get(i, j)) {
					case HouseChars.BLANK:
						worldPane.getHouseModel().setCell(
								HouseModel.HouseObject.BLANK, i, j);
						break;

					case HouseChars.LAMPADINA:
						worldPane.getHouseModel().setCell(
								HouseModel.HouseObject.LAMPADINA_SPENTA, i, j);
						break;

					case HouseChars.PORTA:
						worldPane.getHouseModel().setCell(
								HouseModel.HouseObject.PORTA, i, j);
						break;

					case HouseChars.WALL:
						worldPane.getHouseModel().setCell(
								HouseModel.HouseObject.WALL, i, j);
						break;

					case HouseChars.PERSONA:
						worldPane.getHouseModel().setCell(
								HouseModel.HouseObject.PERSONA, i, j);
						break;
					}
				}
			centerPane = new JScrollPane(worldPane);
			HouseEditor.this.add(centerPane, BorderLayout.CENTER);
			HouseEditor.this.validate();

		}

		private void writeToFile(File outFile) throws IOException {
			BaseHouseWriter writer = new BaseHouseWriter(
					new FileWriter(outFile));
			HouseModel model = worldPane.getHouseModel();

			for (int i = 0; i < model.getHeight(); i++) {
				for (int j = 0; j < model.getWidth(); j++)
					if (model.getCell(i, j) == HouseModel.HouseObject.BLANK) {
						writer.add(HouseChars.BLANK);
					} else if (model.getCell(i, j) == HouseModel.HouseObject.LAMPADINA_SPENTA) {
						writer.add(HouseChars.LAMPADINA);
					} else if (model.getCell(i, j) == HouseModel.HouseObject.WALL) {
						writer.add(HouseChars.WALL);
					} else if (model.getCell(i, j) == HouseModel.HouseObject.PERSONA) {
						writer.add(HouseChars.PERSONA);
					} else if (model.getCell(i, j) == HouseModel.HouseObject.PORTA) {
						writer.add(HouseChars.PORTA);
					}
				writer.nextRow();
			}

			writer.close();
		}

	}
}
